import { HttpException, HttpStatus, Injectable } from '@nestjs/common'
import { InjectRepository } from '@nestjs/typeorm'
import * as argon2 from 'argon2'
import { validate } from 'class-validator'
import { getRepository, Repository } from 'typeorm'
import { UserEntity } from './user.entity'
import { CreateUserDto } from './dto/create-user.dto'
import { ResultFormat } from '../../format/ResultFormat'
import { CacheService } from '../cache/cache.service'
import { LoginUserDto } from './dto/login-user.dto'

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(UserEntity)
    private readonly userRepository: Repository<UserEntity>,
    private readonly cacheService: CacheService
  ) {}

  /**
   * 创建用户
   * @param {CreateUserDto} dto
   */
  async create(dto: CreateUserDto): Promise<ResultFormat> {
    // 查询数据库中是否存在邮箱
    let { nickName, photoUrl, loginEmail, password, code } = dto
    code = Number(code)
    const cacheCode = await this.cacheService.get(loginEmail)
    const user = await getRepository(UserEntity).findOne({ where: { loginEmail } })
    // .createQueryBuilder('user')
    // .where('user.loginEmail = :loginEmail', { loginEmail })
    // .getOne()

    if (user) {
      // const errors = { loginEmail: '请勿重复注册' }
      // throw new HttpException({ errors }, HttpStatus.BAD_REQUEST)
      return new ResultFormat(0, null, false, '请勿重复注册')
    }

    // 判断用户输入的验证码是否等于 redis 缓存的 code
    if (code !== cacheCode) {
      return new ResultFormat(0, null, false, '验证码错误')
    }

    // 如果没有相同邮箱 则创建用户
    let newUser = new UserEntity()
    newUser.nickName = nickName
    newUser.photoUrl = photoUrl
    newUser.loginEmail = loginEmail
    newUser.password = password

    const errors = await validate(newUser)
    if (!errors.length) {
      await this.userRepository.save(newUser)
      await this.cacheService.del(loginEmail)
      return new ResultFormat(0, null, true, '注册成功')
    }
  }

  async findOne({ loginEmail, password }: LoginUserDto): Promise<UserEntity> {
    const user = await this.userRepository.findOne({ loginEmail })
    if (!user) {
      return null
    }
    if (await argon2.verify(user.password, password)) {
      return user
    }

    return null
  }
}
